4(A) : Showing the data as a column chart (simple) Using HTML5 and D3.js and Canvas.js

 

 Data Visualization 

( 3160717 )

Practical and Source Codes



<!DOCTYPE HTML>
<html>

<head>
    <title>Showing the Data as a column chart using D3.js</title>
    <meta charset="utf-8">
    <meta name="author" content="SidPro" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <meta name="description" content="Data visualization using javaScript and HTML" />
    <script src="js/jquery-3.5.1.min.js"></script>
    <script src="js/d3.v5.min.js"></script>
    <style>
        body {
            font-family: 'Open Sans', sans-serif;
        }

        div#layout {
            text-align: center;
        }

        div#container {
            width: 1000px;
            height: 600px;
            margin: auto;
            background-color: #2F4A6D;
        }

        svg {
            width: 100%;
            height: 100%;
        }

        .bar {
            fill: #80cbc4;
        }

        text {
            font-size: 12px;
            fill: #fff;
        }

        path {
            stroke: gray;
        }

        line {
            stroke: gray;
        }

        line#limit {
            stroke: #FED966;
            stroke-width: 3;
            stroke-dasharray: 3 6;
        }

        .grid path {
            stroke-width: 0;
        }

        .grid .tick line {
            stroke: #9FAAAE;
            stroke-opacity: 0.3;
        }

        text.divergence {
            font-size: 14px;
            fill: #2F4A6D;
        }

        text.value {
            font-size: 14px;
        }

        text.title {
            font-size: 22px;
            font-weight: 600;
        }

        text.label {
            font-size: 14px;
            font-weight: 400;
        }

        text.source {
            font-size: 10px;
        }
    </style>
</head>

<body>
    <h2>Showing the Data as a column chart using D3.js </h2>
    <div id='layout'>
        <div id='container'>
            <svg />
        </div>
    </div>
</body>
<script>
    var month = 2;
    var data = [];
    var data;
    $(document).ready(function () {
        $.get('data/data.csv', function (theData) {
            theData = theData.replace(/"/g, '');
            theData = theData.split(/\r?\n|\r/);

            totalRows = theData.length;

            totalRows = theData.length;
            theHead = theData[0].split(',');
            theRow = theData[month].split(',');
            for (let i = 1; i < theHead.length - 2; ++i) {
                myVinyls = {};
                myVinyls["saleType"] = theHead[i];
                myVinyls["saleAmount"] = parseInt(theRow[i]);
                data.push(myVinyls);
            }
            console.log(data);

            //https://blog.risingstack.com/d3-js-tutorial-bar-charts-with-javascript/

            const margin = 80; // margin value which gives a little extra padding to the chart
            const width = 1000 - 2 * margin;
            const height = 600 - 2 * margin;

            const svg = d3.select('svg');
            const svgContainer = d3.select('#container');
            // Padding can be applied with a <g> element translated by the desired value.
            const chart = svg.append('g').attr('transform', `translate(${margin}, ${margin})`);

            /*
                It converts a continuous input domain into a continuous output range.
                Notice the range and domain method. The first one takes the length that
                should be divided between the limits of the domain values.
            */
            // the SVG coordinate system starts from the top left corner that’s why
            // the range takes the height as the first parameter and not zero.
            const yScale = d3.scaleLinear().range([height, 0]).domain([0, 6000]);

            // axis on the left is as simple as adding another group and calling d3’s
            // axisLeft method with the scaling function as a parameter
            chart.append('g').call(d3.axisLeft(yScale));

            const xScale = d3.scaleBand()
                .range([0, width])
                .domain(data.map((d) => d.saleType))
                .padding(0.2);

            chart.append('g')
                .attr('transform', `translate(0, ${height})`)
                .call(d3.axisBottom(xScale));

            const makeYLines = () => d3.axisLeft().scale(yScale)
            chart.append('g').call(d3.axisLeft(yScale));

            // vertical grid lines
            // chart.append('g')
            //   .attr('class', 'grid')
            //   .attr('transform', `translate(0, ${height})`)
            //   .call(makeXLines()
            //     .tickSize(-height, 0, 0)
            //     .tickFormat('')
            //   )

            chart.append('g')
                .attr('class', 'grid')
                .call(makeYLines()
                    .tickSize(-width, 0, 0)
                    .tickFormat('')
                );

            /*
            selectAll elements on the chart which returns with an empty result set. Then, data function tells how many
            elements the DOM should be updated with based on the array length. enter identifies elements that are missing if
            the data input is longer than the selection. This returns a new selection representing the elements that need to
            be added. Usually, this is followed by an append which adds elements to the DOM.
            */



            const barGroups = chart.selectAll()
                .data(data)
                .enter()
                .append('g');

            barGroups
                .append('rect')
                .attr('class', 'bar')
                .attr('x', (g) => xScale(g.saleType))
                .attr('y', (g) => yScale(g.saleAmount))
                .attr('height', (g) => height - yScale(g.saleAmount))
                .attr('width', xScale.bandwidth())
                .on('mouseenter', function (actual, i) {
                    console.log(actual.saleAmount);
                    d3.selectAll('.value')
                        .attr('opacity', 0)

                    d3.select(this)
                        .transition()
                        .duration(300)
                        .attr('opacity', 0.6)
                        .attr('x', (a) => xScale(a.saleType) - 5)
                        .attr('width', xScale.bandwidth() + 10)

                    const y = yScale(actual.saleAmount)

                    line = chart.append('line')
                        .attr('id', 'limit')
                        .attr('x1', 0)
                        .attr('y1', y)
                        .attr('x2', width)
                        .attr('y2', y)

                    barGroups.append('text')
                        .attr('class', 'divergence')
                        .attr('x', (a) => xScale(a.saleType) + xScale.bandwidth() / 2)
                        .attr('y', (a) => yScale(a.saleAmount) + 30)
                        .attr('fill', 'white')
                        .attr('text-anchor', 'middle')
                        .text((a, idx) => {
                            console.log(a.saleAmount);
                            console.log(actual.saleAmount);
                            const divergence = (a.saleAmount - actual.saleAmount).toFixed(1)

                            let text = ''
                            if (divergence > 0) text += '+'
                            text += `${divergence}`

                            return idx !== i ? text : '';
                        })

                })
                .on('mouseleave', function () {
                    d3.selectAll('.value')
                        .attr('opacity', 1)

                    d3.select(this)
                        .transition()
                        .duration(300)
                        .attr('opacity', 1)
                        .attr('x', (a) => xScale(a.saleType))
                        .attr('width', xScale.bandwidth())

                    chart.selectAll('#limit').remove()
                    chart.selectAll('.divergence').remove()
                })
            /*chart.selectAll()
                .data(data.length)
                .enter()
                .append('rect')
                .attr('x', (s) => xScale(s.saleType))
                .attr('y', (s) => yScale(s.saleAmount))
                .attr('height', (s) => height - yScale(s.saleAmount))
                .attr('width', xScale.bandwidth())
                .attr('x', (actual, index, data) => xScale(actual.saleAmount));     */

            barGroups
                .append('text')
                .attr('class', 'value')
                .attr('x', (a) => xScale(a.saleType) + xScale.bandwidth() / 2)
                .attr('y', (a) => yScale(a.saleAmount) + 30)
                .attr('text-anchor', 'middle')
                .text((a) => `${a.saleAmount}`)

            svg
                .append('text')
                .attr('class', 'label')
                .attr('x', -(height / 2) - margin)
                .attr('y', margin / 2.4)
                .attr('transform', 'rotate(-90)')
                .attr('text-anchor', 'middle')
                .text('sales Unit')

            svg.append('text')
                .attr('class', 'label')
                .attr('x', width / 2 + margin)
                .attr('y', height + margin * 1.7)
                .attr('text-anchor', 'middle')
                .text('Products sales')

            svg.append('text')
                .attr('class', 'title')
                .attr('x', width / 2 + margin)
                .attr('y', 40)
                .attr('text-anchor', 'middle')
                .text('Sales Data of February Month')

            svg.append('text')
                .attr('class', 'source')
                .attr('x', width - margin / 2)
                .attr('y', height + margin * 1.7)
                .attr('text-anchor', 'start')
                .text('Source: PDS sales.csv, 2020')
        });
    });
</script>

</html>





Go Back

No comments:

Get new posts by email:


APY Logo