Compare commits
	
		
			11 Commits
		
	
	
		
			test-rn
			...
			style-time
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					31720d5a05 | ||
| 
						 | 
					23151d83b9 | ||
| 
						 | 
					c37092e625 | ||
| 
						 | 
					6306f680a8 | ||
| 
						 | 
					aa3b32c337 | ||
| 
						 | 
					9313eefdee | ||
| 
						 | 
					4a6765146f | ||
| 
						 | 
					ad506c56fd | ||
| 
						 | 
					fa0a22c4a0 | ||
| 
						 | 
					0320c77c02 | ||
| 
						 | 
					f4d5743924 | 
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div ref="plan"
 | 
			
		||||
     class="c-plan"
 | 
			
		||||
     class="c-plan c-timeline-holder"
 | 
			
		||||
>
 | 
			
		||||
    <template v-if="viewBounds && !options.compact">
 | 
			
		||||
        <swim-lane>
 | 
			
		||||
@@ -22,10 +22,10 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import * as d3Selection from 'd3-selection';
 | 
			
		||||
import * as d3Scale from 'd3-scale';
 | 
			
		||||
import TimelineAxis from "../../ui/components/TimeSystemAxis.vue";
 | 
			
		||||
import SwimLane from "@/ui/components/swim-lane/SwimLane.vue";
 | 
			
		||||
import { getValidatedPlan } from "./util";
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
 | 
			
		||||
//TODO: UI direction needed for the following property values
 | 
			
		||||
@@ -38,9 +38,8 @@ const RESIZE_POLL_INTERVAL = 200;
 | 
			
		||||
const ROW_HEIGHT = 25;
 | 
			
		||||
const LINE_HEIGHT = 12;
 | 
			
		||||
const MAX_TEXT_WIDTH = 300;
 | 
			
		||||
const EDGE_ROUNDING = 10;
 | 
			
		||||
const DEFAULT_COLOR = 'yellow';
 | 
			
		||||
const DEFAULT_TEXT_COLOR = 'white';
 | 
			
		||||
const EDGE_ROUNDING = 5;
 | 
			
		||||
const DEFAULT_COLOR = '#cc9922';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    components: {
 | 
			
		||||
@@ -72,7 +71,7 @@ export default {
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    mounted() {
 | 
			
		||||
        this.validateJSON(this.domainObject.selectFile.body);
 | 
			
		||||
        this.getPlanData(this.domainObject);
 | 
			
		||||
 | 
			
		||||
        this.canvas = this.$refs.plan.appendChild(document.createElement('canvas'));
 | 
			
		||||
        this.canvas.height = 0;
 | 
			
		||||
@@ -118,14 +117,8 @@ export default {
 | 
			
		||||
 | 
			
		||||
            return clientWidth - 200;
 | 
			
		||||
        },
 | 
			
		||||
        validateJSON(jsonString) {
 | 
			
		||||
            try {
 | 
			
		||||
                this.json = JSON.parse(jsonString);
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        getPlanData(domainObject) {
 | 
			
		||||
            this.planData = getValidatedPlan(domainObject);
 | 
			
		||||
        },
 | 
			
		||||
        updateViewBounds() {
 | 
			
		||||
            this.viewBounds = this.openmct.time.bounds();
 | 
			
		||||
@@ -148,7 +141,8 @@ export default {
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        clearPreviousActivities() {
 | 
			
		||||
            d3Selection.selectAll(".c-plan__contents > div").remove();
 | 
			
		||||
            let activities = this.$el.querySelectorAll(".c-plan__contents > div");
 | 
			
		||||
            activities.forEach(activity => activity.remove());
 | 
			
		||||
        },
 | 
			
		||||
        setDimensions() {
 | 
			
		||||
            const planHolder = this.$refs.plan;
 | 
			
		||||
@@ -231,14 +225,14 @@ export default {
 | 
			
		||||
            return (currentRow || 0);
 | 
			
		||||
        },
 | 
			
		||||
        calculatePlanLayout() {
 | 
			
		||||
            let groups = Object.keys(this.json);
 | 
			
		||||
            let groups = Object.keys(this.planData);
 | 
			
		||||
            this.groupActivities = {};
 | 
			
		||||
 | 
			
		||||
            groups.forEach((key, index) => {
 | 
			
		||||
                let activitiesByRow = {};
 | 
			
		||||
                let currentRow = 0;
 | 
			
		||||
 | 
			
		||||
                let activities = this.json[key];
 | 
			
		||||
                let activities = this.planData[key];
 | 
			
		||||
                activities.forEach((activity) => {
 | 
			
		||||
                    if (this.isActivityInBounds(activity)) {
 | 
			
		||||
                        const currentStart = Math.max(this.viewBounds.start, activity.start);
 | 
			
		||||
@@ -251,6 +245,13 @@ export default {
 | 
			
		||||
                        //TODO: Fix bug for SVG where the rectWidth is not proportional to the canvas measuredWidth of the text
 | 
			
		||||
                        const activityNameFitsRect = (rectWidth >= activityNameWidth);
 | 
			
		||||
                        const textStart = (activityNameFitsRect ? rectX : rectY) + TEXT_LEFT_PADDING;
 | 
			
		||||
                        const color = activity.color || DEFAULT_COLOR;
 | 
			
		||||
                        let textColor = '';
 | 
			
		||||
                        if (activity.textColor) {
 | 
			
		||||
                            textColor = activity.textColor;
 | 
			
		||||
                        } else if (activityNameFitsRect) {
 | 
			
		||||
                            textColor = this.getContrastingColor(color);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        let textLines = this.getActivityDisplayText(this.canvasContext, activity.name, activityNameFitsRect);
 | 
			
		||||
                        const textWidth = textStart + this.getTextWidth(textLines[0]) + TEXT_LEFT_PADDING;
 | 
			
		||||
@@ -269,8 +270,8 @@ export default {
 | 
			
		||||
 | 
			
		||||
                        activitiesByRow[currentRow].push({
 | 
			
		||||
                            activity: {
 | 
			
		||||
                                color: activity.color || DEFAULT_COLOR,
 | 
			
		||||
                                textColor: activity.textColor || DEFAULT_TEXT_COLOR,
 | 
			
		||||
                                color: color,
 | 
			
		||||
                                textColor: textColor,
 | 
			
		||||
                                name: activity.name,
 | 
			
		||||
                                exceeds: {
 | 
			
		||||
                                    start: this.xScale(this.viewBounds.start) > this.xScale(activity.start),
 | 
			
		||||
@@ -279,6 +280,7 @@ export default {
 | 
			
		||||
                            },
 | 
			
		||||
                            textLines: textLines,
 | 
			
		||||
                            textStart: textStart,
 | 
			
		||||
                            textClass: activityNameFitsRect ? "" : "activity-label--outside-rect",
 | 
			
		||||
                            textY: textY,
 | 
			
		||||
                            start: rectX,
 | 
			
		||||
                            end: activityNameFitsRect ? rectY : textStart + textWidth,
 | 
			
		||||
@@ -423,11 +425,14 @@ export default {
 | 
			
		||||
                width = width + EDGE_ROUNDING;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            width = Math.max(width, 1); // Set width to a minimum of 1
 | 
			
		||||
 | 
			
		||||
            // rx: don't round corners if the width of the rect is smaller than the rounding radius
 | 
			
		||||
            this.setNSAttributesForElement(rectElement, {
 | 
			
		||||
                class: 'activity-bounds',
 | 
			
		||||
                x: item.activity.exceeds.start ? item.start - EDGE_ROUNDING : item.start,
 | 
			
		||||
                y: row,
 | 
			
		||||
                rx: EDGE_ROUNDING,
 | 
			
		||||
                rx: (width < EDGE_ROUNDING * 2) ? 0 : EDGE_ROUNDING,
 | 
			
		||||
                width: width,
 | 
			
		||||
                height: String(ROW_HEIGHT),
 | 
			
		||||
                fill: activity.color
 | 
			
		||||
@@ -438,7 +443,7 @@ export default {
 | 
			
		||||
            item.textLines.forEach((line, index) => {
 | 
			
		||||
                let textElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');
 | 
			
		||||
                this.setNSAttributesForElement(textElement, {
 | 
			
		||||
                    class: 'activity-label',
 | 
			
		||||
                    class: `activity-label ${item.textClass}`,
 | 
			
		||||
                    x: item.textStart,
 | 
			
		||||
                    y: item.textY + (index * LINE_HEIGHT),
 | 
			
		||||
                    fill: activity.textColor
 | 
			
		||||
@@ -449,6 +454,29 @@ export default {
 | 
			
		||||
                svgElement.appendChild(textElement);
 | 
			
		||||
            });
 | 
			
		||||
            // this.addForeignElement(svgElement, activity.name, item.textStart, item.textY - LINE_HEIGHT);
 | 
			
		||||
        },
 | 
			
		||||
        cutHex(h, start, end) {
 | 
			
		||||
            const hStr = (h.charAt(0) === '#') ? h.substring(1, 7) : h;
 | 
			
		||||
 | 
			
		||||
            return parseInt(hStr.substring(start, end), 16);
 | 
			
		||||
        },
 | 
			
		||||
        getContrastingColor(hexColor) {
 | 
			
		||||
            // https://codepen.io/davidhalford/pen/ywEva/
 | 
			
		||||
            // TODO: move this into a general utility function?
 | 
			
		||||
            const cThreshold = 130;
 | 
			
		||||
 | 
			
		||||
            if (hexColor.indexOf('#') === -1) {
 | 
			
		||||
                // We weren't given a hex color
 | 
			
		||||
                return "#ff0000";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const hR = this.cutHex(hexColor, 0, 2);
 | 
			
		||||
            const hG = this.cutHex(hexColor, 2, 4);
 | 
			
		||||
            const hB = this.cutHex(hexColor, 4, 6);
 | 
			
		||||
 | 
			
		||||
            const cBrightness = ((hR * 299) + (hG * 587) + (hB * 114)) / 1000;
 | 
			
		||||
 | 
			
		||||
            return cBrightness > cThreshold ? "#000000" : "#ffffff";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +1,16 @@
 | 
			
		||||
.c-plan {
 | 
			
		||||
 | 
			
		||||
  @include abs();
 | 
			
		||||
 | 
			
		||||
  svg {
 | 
			
		||||
    text-rendering: geometricPrecision;
 | 
			
		||||
 | 
			
		||||
    .activity-label, .no-activities {
 | 
			
		||||
    text {
 | 
			
		||||
      stroke: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .no-activities {
 | 
			
		||||
      fill: #383838;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .activity-bounds {
 | 
			
		||||
      fill-opacity: 0.5;
 | 
			
		||||
    }
 | 
			
		||||
      .activity-label {
 | 
			
		||||
          &--outside-rect {
 | 
			
		||||
              fill: $colorBodyFg !important;
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  canvas {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								src/plugins/plan/util.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/plugins/plan/util.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
export function getValidatedPlan(domainObject) {
 | 
			
		||||
    let jsonString = domainObject.selectFile.body;
 | 
			
		||||
    let json = {};
 | 
			
		||||
    try {
 | 
			
		||||
        json = JSON.parse(jsonString);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        return json;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return json;
 | 
			
		||||
}
 | 
			
		||||
@@ -55,7 +55,7 @@
 | 
			
		||||
                <swim-lane :icon-class="item.type.definition.cssClass"
 | 
			
		||||
                           :min-height="item.height"
 | 
			
		||||
                           :show-ucontents="item.domainObject.type === 'plan'"
 | 
			
		||||
                           :span-rows="item.domainObject.type === 'plan'"
 | 
			
		||||
                           :span-rows-count="item.rowCount"
 | 
			
		||||
                >
 | 
			
		||||
                    <template slot="label">
 | 
			
		||||
                        {{ item.domainObject.name }}
 | 
			
		||||
@@ -78,6 +78,7 @@
 | 
			
		||||
import ObjectView from '@/ui/components/ObjectView.vue';
 | 
			
		||||
import TimelineAxis from '../../ui/components/TimeSystemAxis.vue';
 | 
			
		||||
import SwimLane from "@/ui/components/swim-lane/SwimLane.vue";
 | 
			
		||||
import { getValidatedPlan } from "../plan/util";
 | 
			
		||||
 | 
			
		||||
const unknownObjectType = {
 | 
			
		||||
    definition: {
 | 
			
		||||
@@ -116,6 +117,8 @@ export default {
 | 
			
		||||
        this.composition.off('add', this.addItem);
 | 
			
		||||
        this.composition.off('remove', this.removeItem);
 | 
			
		||||
        this.composition.off('reorder', this.reorder);
 | 
			
		||||
        this.openmct.time.off("bounds", this.updateViewBounds);
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    mounted() {
 | 
			
		||||
        if (this.composition) {
 | 
			
		||||
@@ -126,6 +129,7 @@ export default {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.getTimeSystems();
 | 
			
		||||
        this.openmct.time.on("bounds", this.updateViewBounds);
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
        addItem(domainObject) {
 | 
			
		||||
@@ -133,6 +137,10 @@ export default {
 | 
			
		||||
            let keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
 | 
			
		||||
            let objectPath = [domainObject].concat(this.objectPath.slice());
 | 
			
		||||
            let viewKey = getViewKey(domainObject, this.openmct);
 | 
			
		||||
            let rowCount = 0;
 | 
			
		||||
            if (domainObject.type === 'plan') {
 | 
			
		||||
                rowCount = Object.keys(getValidatedPlan(domainObject)).length;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let height = domainObject.type === 'telemetry.plot.stacked' ? `${domainObject.composition.length * 100}px` : '100px';
 | 
			
		||||
            let item = {
 | 
			
		||||
@@ -141,6 +149,7 @@ export default {
 | 
			
		||||
                type,
 | 
			
		||||
                keyString,
 | 
			
		||||
                viewKey,
 | 
			
		||||
                rowCount,
 | 
			
		||||
                height
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
@@ -174,6 +183,12 @@ export default {
 | 
			
		||||
 | 
			
		||||
            //TODO: Some kind of translation via an offset? of current bounds to target timeSystem
 | 
			
		||||
            return currentBounds;
 | 
			
		||||
        },
 | 
			
		||||
        updateViewBounds(bounds) {
 | 
			
		||||
            let currentTimeSystem = this.timeSystems.find(item => item.timeSystem.key === this.openmct.time.timeSystem().key);
 | 
			
		||||
            if (currentTimeSystem) {
 | 
			
		||||
                currentTimeSystem.bounds = bounds;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
 | 
			
		||||
import { createOpenMct, resetApplicationState } from "utils/testing";
 | 
			
		||||
import TimelinePlugin from "./plugin";
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
describe('the plugin', function () {
 | 
			
		||||
    let objectDef;
 | 
			
		||||
@@ -47,7 +48,7 @@ describe('the plugin', function () {
 | 
			
		||||
        child.style.height = '480px';
 | 
			
		||||
        element.appendChild(child);
 | 
			
		||||
 | 
			
		||||
        openmct.time.bounds({
 | 
			
		||||
        openmct.time.timeSystem('utc', {
 | 
			
		||||
            start: 1597160002854,
 | 
			
		||||
            end: 1597181232854
 | 
			
		||||
        });
 | 
			
		||||
@@ -75,18 +76,32 @@ describe('the plugin', function () {
 | 
			
		||||
        it('is creatable', () => {
 | 
			
		||||
            expect(objectDef.creatable).toEqual(mockObject.creatable);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
        it('provides a timeline view', () => {
 | 
			
		||||
    describe('the view', () => {
 | 
			
		||||
        let timelineView;
 | 
			
		||||
 | 
			
		||||
        beforeEach((done) => {
 | 
			
		||||
            const testViewObject = {
 | 
			
		||||
                id: "test-object",
 | 
			
		||||
                type: "time-strip"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const applicableViews = openmct.objectViews.get(testViewObject);
 | 
			
		||||
            let timelineView = applicableViews.find((viewProvider) => viewProvider.key === 'time-strip.view');
 | 
			
		||||
            timelineView = applicableViews.find((viewProvider) => viewProvider.key === 'time-strip.view');
 | 
			
		||||
            let view = timelineView.view(testViewObject, element);
 | 
			
		||||
            view.show(child, true);
 | 
			
		||||
            Vue.nextTick(done);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('provides a view', () => {
 | 
			
		||||
            expect(timelineView).toBeDefined();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('displays a time axis', () => {
 | 
			
		||||
            const el = element.querySelector('.c-timesystem-axis');
 | 
			
		||||
            expect(el).toBeDefined();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,4 @@
 | 
			
		||||
.c-timeline-holder {
 | 
			
		||||
  @include abs();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-timeline {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
    @include abs();
 | 
			
		||||
    overflow-x: hidden;
 | 
			
		||||
}
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
@import "../ui/components/object-label.scss";
 | 
			
		||||
@import "../ui/components/progress-bar.scss";
 | 
			
		||||
@import "../ui/components/search.scss";
 | 
			
		||||
@import "../ui/components/swim-lane/swim-lane.scss";
 | 
			
		||||
@import "../ui/components/swim-lane/swimlane.scss";
 | 
			
		||||
@import "../ui/components/toggle-switch.scss";
 | 
			
		||||
@import "../ui/components/timesystem-axis.scss";
 | 
			
		||||
@import "../ui/inspector/elements.scss";
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,11 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="u-contents"
 | 
			
		||||
     :class="{'c-swim-lane': !isNested}"
 | 
			
		||||
     :class="{'c-swimlane': !isNested}"
 | 
			
		||||
>
 | 
			
		||||
 | 
			
		||||
    <div class="c-swim-lane__lane-label c-object-label"
 | 
			
		||||
         :class="{'c-swim-lane__lane-label--span-rows': spanRows, 'c-swim-lane__lane-label--span-cols': (!spanRows && !isNested)}"
 | 
			
		||||
    <div class="c-swimlane__lane-label c-object-label"
 | 
			
		||||
         :class="{'c-swimlane__lane-label--span-cols': (!spanRowsCount && !isNested)}"
 | 
			
		||||
         :style="gridRowSpan"
 | 
			
		||||
    >
 | 
			
		||||
        <div v-if="iconClass"
 | 
			
		||||
             class="c-object-label__type-icon"
 | 
			
		||||
@@ -17,7 +18,7 @@
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="c-swim-lane__lane-object"
 | 
			
		||||
    <div class="c-swimlane__lane-object"
 | 
			
		||||
         :style="{'min-height': minHeight}"
 | 
			
		||||
         :class="{'u-contents': showUcontents}"
 | 
			
		||||
         data-selectable
 | 
			
		||||
@@ -55,10 +56,19 @@ export default {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        spanRows: {
 | 
			
		||||
            type: Boolean,
 | 
			
		||||
        spanRowsCount: {
 | 
			
		||||
            type: Number,
 | 
			
		||||
            default() {
 | 
			
		||||
                return false;
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    computed: {
 | 
			
		||||
        gridRowSpan() {
 | 
			
		||||
            if (this.spanRowsCount) {
 | 
			
		||||
                return `grid-row: span ${this.spanRowsCount}`;
 | 
			
		||||
            } else {
 | 
			
		||||
                return '';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
.c-swim-lane {
 | 
			
		||||
  display: grid;
 | 
			
		||||
  grid-template-columns: 100px 100px 1fr;
 | 
			
		||||
  grid-column-gap: 1px;
 | 
			
		||||
  grid-row-gap: 1px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
 | 
			
		||||
  [class*='__lane-label'] {
 | 
			
		||||
    background: rgba($colorBodyFg, 0.2); // TODO: convert to theme constant
 | 
			
		||||
    color: $colorBodyFg; // TODO: convert to theme constant
 | 
			
		||||
    padding: $interiorMarginSm;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [class*='--span-cols'] {
 | 
			
		||||
    grid-column: span 2;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [class*='--span-rows'] {
 | 
			
		||||
    grid-row: span 4;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &__lane-object {
 | 
			
		||||
    .c-plan {
 | 
			
		||||
      display: contents;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								src/ui/components/swim-lane/swimlane.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/ui/components/swim-lane/swimlane.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
.c-swimlane {
 | 
			
		||||
    display: grid;
 | 
			
		||||
    grid-template-columns: 100px 100px 1fr;
 | 
			
		||||
    grid-column-gap: 1px;
 | 
			
		||||
    grid-row-gap: 1px;
 | 
			
		||||
    margin-bottom: 1px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
 | 
			
		||||
    [class*='__lane-label'] {
 | 
			
		||||
        background: rgba($colorBodyFg, 0.2);
 | 
			
		||||
        color: $colorBodyFg;
 | 
			
		||||
        padding: $interiorMarginSm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [class*='--span-cols'] {
 | 
			
		||||
        grid-column: span 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [class*='--span-rows'] {
 | 
			
		||||
        grid-row: span 4;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__lane-object {
 | 
			
		||||
        background: rgba(black, 0.1);
 | 
			
		||||
 | 
			
		||||
        .c-plan {
 | 
			
		||||
            display: contents;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,35 +1,42 @@
 | 
			
		||||
.c-timesystem-axis {
 | 
			
		||||
  $h: 30px;
 | 
			
		||||
  height: $h;
 | 
			
		||||
    $h: 30px;
 | 
			
		||||
    height: $h;
 | 
			
		||||
 | 
			
		||||
  svg {
 | 
			
		||||
    text-rendering: geometricPrecision;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    svg {
 | 
			
		||||
        $lineC: rgba($colorBodyFg, 0.3) !important;
 | 
			
		||||
        text-rendering: geometricPrecision;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
 | 
			
		||||
    text:not(.activity) {
 | 
			
		||||
      // Tick labels
 | 
			
		||||
      fill: $colorBodyFg;
 | 
			
		||||
      paint-order: stroke;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      stroke: $colorBodyBg;
 | 
			
		||||
      stroke-linecap: butt;
 | 
			
		||||
      stroke-linejoin: bevel;
 | 
			
		||||
      stroke-width: 6px;
 | 
			
		||||
        .domain {
 | 
			
		||||
            stroke: $lineC;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .tick {
 | 
			
		||||
            line {
 | 
			
		||||
                stroke: $lineC;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            text {
 | 
			
		||||
                // Tick labels
 | 
			
		||||
                fill: $colorBodyFg;
 | 
			
		||||
                paint-order: stroke;
 | 
			
		||||
                font-weight: bold;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .nowMarker {
 | 
			
		||||
    width: 2px;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    z-index: 10;
 | 
			
		||||
    background: gray;
 | 
			
		||||
    .nowMarker {
 | 
			
		||||
        width: 2px;
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        z-index: 10;
 | 
			
		||||
        background: gray;
 | 
			
		||||
 | 
			
		||||
    & .icon-arrow-down {
 | 
			
		||||
      font-size: large;
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      top: -8px;
 | 
			
		||||
      left: -8px;
 | 
			
		||||
        & .icon-arrow-down {
 | 
			
		||||
            font-size: large;
 | 
			
		||||
            position: absolute;
 | 
			
		||||
            top: -8px;
 | 
			
		||||
            left: -8px;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user