Showing posts with label jsfiddle. Show all posts
Showing posts with label jsfiddle. Show all posts

Thursday, November 27, 2014

File input control don't have to be ugly    

The caption is a bit of a lie, it has to be ugly, since native browser implementation is pretty ugly and there is no straight forward way to change it's L&F.

So what do you do when your have a nice bootstrap  L&F in the whole system?

This fiddle suggesting a nice solution that was inspired by this guy.

I've used it together with AngularJS file uploader directive and it looks and works pretty nice good together.

In general the solution is :

  1. To make the sure you file input tag is transparent 
  2. To increase it's z-index so it will be above
  3. To locate it on the same spot a nice looking control is located
  4. To make sure z-index of nice looking control is lower than the file input tag

Actually that all the story, if anyone familiar with better techniques to prettify file input tag, please leave a comment bellow.



Saturday, May 17, 2014

Linear gauge with gradient fill

In my searches for linear gauge control I didn't find any viable solution.
So I've created one based on D3 stacked bar graph.
See JSFiddle for implementation details

The final result will be something like this:


The Html will be pretty simple, only the container where we will put all the drawing

<div id="linearGaugeContainer"></div>

 I'm using SVG gradients definition in this sample

<!--define svg gradients to be used in java script. make sure the svg tag takes no room on your page=> width and height = 0px-->
<svg style="height: 0px; width: 0px;" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <lineargradient id="NORMAL_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#C1DC99" stop-opacity="1">
            <stop offset="100%" stop-color="#669900" stop-opacity="1">
        </stop></stop></lineargradient>
        <lineargradient id="WARNING_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#84C6F6" stop-opacity="1">
            <stop offset="100%" stop-color="#6FA7CF" stop-opacity="1">
        </stop></stop></lineargradient>
        <lineargradient id="MINOR_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#FFE537" stop-opacity="1">
            <stop offset="100%" stop-color="#F9C328" stop-opacity="1">
        </stop></stop></lineargradient>
        <lineargradient id="MAJOR_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#FF9900" stop-opacity="1">
            <stop offset="100%" stop-color="#FF6700" stop-opacity="1">
        </stop></stop></lineargradient>
        <lineargradient id="CRITICAL_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#E70030" stop-opacity="1">
            <stop offset="100%" stop-color="#B30020" stop-opacity="1">
        </stop></stop></lineargradient>
    </defs>
</svg>

The javascript code is a bit long, just follow the comments within the code:

//Linear gauge
//The way to implement it would be: 
// - To take a stacked bar graph as a basis
// - Ignore all the graph related attributes 
//   (like: axis, ticks and so on)
// - Define a single set of data 
// - Swap the x and y axis values
var margins = {
    top: 12,
    left: 48,
    right: 24,
    bottom: 24
},
width = 700 - margins.left - margins.right
    height = 15,
    dataset = [{
        data: [{
            barId: '1', // we assign some random value, the most important to keep it same for all the entries 
            percent: 0.1, // percentage that we want a specific value to occupy as a part of the gauge: values betwee 0-1
            severity: 'NORMAL_COLOR'// color id that we'll used to reference gradient value
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.4,
            severity: 'WARNING_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.22,
            severity: 'MINOR_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.2,
            severity: 'MAJOR_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.08,
            severity: 'CRITICAL_COLOR'
        }]
    }],
    dataset = dataset.map(function (d) {
        return d.data.map(function (o, i) {
            // Structure it so that your numeric
            // axis (the stacked amount) is y
            return {
                y: o.percent,
                x: o.barId,
                severity:o.severity
            };
        });
    }),
    stack = d3.layout.stack();

stack(dataset);


var dataset = dataset.map(function (group) {
    return group.map(function (d) {
        // Invert the x and y values, and y0 becomes x0
        return {
            x: d.y,
            y: d.x,
            x0: d.y0,
            severity:d.severity
            
        };
    });
}),
    svg = d3.select('#linearGaugeContainer')
        .append('svg')
        .attr('width', width + margins.left + margins.right)
        .attr('height', height + margins.top + margins.bottom)
        .append('g')
        .attr('transform', 'translate(' + margins.left + ',' + margins.top + ')'),
    xMax = d3.max(dataset, function (group) {
        return d3.max(group, function (d) {
            return d.x + d.x0;
        });
    }),
    xScale = d3.scale.linear()
        .domain([0, xMax])
        .range([0, width]),
    yValue = dataset[0].map(function (d) {
        return d.y;
    }),
    yScale = d3.scale.ordinal()
        .domain(yValue)
        .rangeRoundBands([0, height], .1),
    // this color funciton referencing the linearGradient defind in the HTML part by id 
    color = function (index) {
        console.log(dataset[index][0])
        return "url(#" + dataset[index][0].severity + ")";
    },
    groups = svg.selectAll('g')
        .data(dataset)
        .enter()
        .append('g')
        .style('fill', function (d, i) {
        return color(i);
    });
    var rects = groups.selectAll('rect')
        .data(function (d) {
        return d;
    }).enter();
    rects.append('rect')
        .attr('x', function (d) {
        return xScale(d.x0);
    })
        .attr('y', function (d, i) {
        return yScale(d.y);
    })
        .attr('height', function (d) {
        return yScale.rangeBand();
    })
        .attr('width', function (d) {
        return xScale(d.x);
    });
// locate a label with percentage above each section of the gauge    
rects.append("text")
      .text(function(d,i) { return (d.x * 100) + '%' })
      .attr("x", function(d) { return xScale(d.x0); })
      .style("stroke", '#000000')

Wednesday, February 5, 2014

Google style gauge using D3.js

As a part of a dashboard I'm currently implementing I've popped into great job done by Tomer Doron
For my needs I've tweaked it a bit, see the following jFiddle link.